/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021/11/21     Lyons        first version
 */

/*
 * rt_base_t rt_hw_interrupt_disable(void);
 */
    .globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
    csrr    a0, mstatus
    and     t0, a0, 0xfffffff7
    csrw    mstatus, t0
    ret

/*
 * void rt_hw_interrupt_enable(rt_base_t level);
 */
    .globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
    csrw    mstatus, a0
    ret

/*
 * void rt_hw_context_switch_to(rt_uint32 to);
 *
 * r0 --> to
 */
    .globl rt_hw_context_switch_to
rt_hw_context_switch_to:
    la      a4, rt_interrupt_from_thread
    sw      zero, 0(a4)

    la      a4, rt_interrupt_to_thread
    sw      a0, 0(a4)

    la      a4, rt_interrupt_nest
    sb      zero, 0(a4)

    la      a4, rt_thread_switch_interrupt_flag
    sw      zero, 0(a4)

    lw      a4, rt_interrupt_to_thread
    lw      sp, 0(a4)

    lw      a5, 116(sp)
    csrw    mepc, a5

    lw      x1,  0(sp)
    lw      x5,  8(sp)
    lw      x6,  12(sp)
    lw      x7,  16(sp)
    lw      x8,  20(sp)
    lw      x9,  24(sp)
    lw      x10, 28(sp)
    lw      x11, 32(sp)
    lw      x12, 36(sp)
    lw      x13, 40(sp)
    lw      x14, 44(sp)
    lw      x15, 48(sp)
    lw      x16, 52(sp)
    lw      x17, 56(sp)
    lw      x18, 60(sp)
    lw      x19, 64(sp)
    lw      x20, 68(sp)
    lw      x21, 72(sp)
    lw      x22, 76(sp)
    lw      x23, 80(sp)
    lw      x24, 84(sp)
    lw      x25, 88(sp)
    lw      x26, 92(sp)
    lw      x27, 96(sp)
    lw      x28, 100(sp)
    lw      x29, 104(sp)
    lw      x30, 108(sp)
    lw      x31, 112(sp)

    addi    sp, sp, 120

    li      a5, 0x00001888
    csrw    mstatus, a5

    csrr    a5, mepc
    jr      a5

/*
 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
 *
 * a0 --> from
 * a1 --> to
 */
    .global rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
    .globl rt_hw_context_switch
rt_hw_context_switch:
    la      a4, rt_interrupt_from_thread
    sw      a0, 0(a4)

    la      a4, rt_interrupt_to_thread
    sw      a1, 0(a4)

    la      a4, rt_thread_switch_interrupt_flag
    li      a5, 1
    sw      a5, 0(a4)

    ret
